home *** CD-ROM | disk | FTP | other *** search
- /* FIXDPMI.C - Fixes Borland C++ 3.0 DPMILOAD.EXE
- * to work properly under DESQVIEW
- *
- * DPMILOAD mishandled setting it's own termination address
- * by setting only the OFFSET at PSP:000Ah instead of the
- * entire FAR POINTER. Since DV intercepts all terminations,
- * and DPMILOAD had already terminated once as a TSR, the
- * SEGMENT of the termination address was pointing into DV
- * code, so when the OFFSET only was changed before the second
- * exit, the 4C00, INT 21 call exited to nonsense.
-
- * This patch rearranges the portion of code which blew it
- * and unloads the TSR DPMILOAD from memory correctly.
-
- * This patch fixes DPMILOAD so you can load any DPMI BC++ 3.0 TOOL
- * in a window under DV. The only unusual setting I use is Keyboard
- * conflict 8. The IDE still likes to steal some of the <ALT> key
- * presses.
-
- * To spare you debug manipulations, I wrote this short program
- * If you don't have a 'C' compiler, use the binary I've provided
- *
- * If you have any questions, or problems, feel free to contact me.
- *
- * Philip B. Gardner 70053,3157
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <process.h>
-
- char help[] = "fixdpmi (dpmiload.exe's pathname) [-u]\n"
- " -u is optional and reverses the patch" ;
- #define datalen 88
-
- unsigned char patch[3][datalen] = {
- {
- 0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x8B,
- 0xDC,0x8B,0xEC,0x8B,0x4E,0x04,0x8B,0x26,
- 0x0F,0x00,0x8E,0x16,0x07,0x00,0x51,0x83,
- 0xEB,0x0E,0x53,0x50,0xE8,0x82,0x00,0xE8,
- 0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
- 0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
- 0x00,0x58,0x5B,0x59,0x8B,0x16,0x0B,0x00,
- 0x8E,0xC2,0x8B,0x16,0x6C,0x00,0x26,0x89,
- 0x16,0x10,0x00,0x26,0x89,0x0E,0x0A,0x00,
- 0x8E,0xC2,0x26,0x89,0x1E,0x2E,0x00,0x26,
- 0xA3,0x30,0x00,0xB8,0x00,0x4C,0xCD,0x21
- },
- {
- 0x5E,0x07,0x1F,0xEB,0x88,0x8C,0xD0,0x89,
- 0xE5,0xC4,0x4E,0x04,0x8B,0x26,0x0F,0x00,
- 0x8E,0x16,0x07,0x00,0x50,0x83,0xED,0x0E,
- 0x55,0x51,0x06,0x90,0xE8,0x82,0x00,0xE8,
- 0xA6,0xD1,0xE8,0x19,0xFC,0xE8,0x67,0x00,
- 0xE8,0x52,0x00,0xE8,0x9A,0x00,0xE8,0xBB,
- 0x00,0x8B,0x16,0x6C,0x00,0x8E,0x1E,0x0B,
- 0x00,0x89,0x16,0x10,0x00,0x8F,0x06,0x0C,
- 0x00,0x8F,0x06,0x0A,0x00,0x8E,0xDA,0x8F,
- 0x06,0x2E,0x00,0x8F,0x06,0x30,0x00,0xEB,
- 0x00,0xEB,0x00,0xB8,0x00,0x4C,0xCD,0x21
- }
- } ;
-
- #define start (0x3A68L)
- #define broke (patch[0])
- #define fixit (patch[1])
- #define buffer (patch[2])
-
- void main(int argc, char *argv[])
- {
- FILE *fp ;
- int state ;
- char *search = broke ;
- char *update = fixit ;
-
- for(state = 4 ; state ; state--)
-
- switch(state) {
-
- case 4:
- if (argc < 2) {
- puts(help) ;
- goto out ;
- }
- break ;
- case 3:
- if ((fp = fopen(argv[1],"rb+")) == NULL) {
- printf("Unable able to open %s\n",argv[1]) ;
- goto out ;
- }
- if (argc > 2 && argv[2][0] == '-') {
- switch(argv[2][1]) {
- case 'u':
- case 'U':
- update = broke ;
- search = fixit ;
- }
- }
- break ;
- case 2:
- if (fseek(fp,start,SEEK_SET)
- || fread(buffer,1,datalen,fp) != datalen
- || memcmp(buffer,search,datalen)) {
- printf("Wrong version of %s\n",argv[1]) ;
- goto out ;
- }
- break ;
- case 1:
- if (fseek(fp,-datalen,SEEK_CUR)
- || fwrite(update,1,datalen,fp) != datalen) {
- printf("Error patching %s\n",argv[1]) ;
- goto out ;
- }
- break ;
- case 0:
- printf("Successfully patched %s\n",argv[1]) ;
- }
-
- out:
- if (fp != NULL) fclose(fp) ;
- exit(state) ;
- }
-
- /* ---------- BUG ----------
-
- MOV AX,SS ; segment=int 2Fh vector,offset=386d
- MOV BX,SP
- MOV BP,SP
- MOV CX,[BP+04] ; CX = offset of new termination address
- MOV SP,[000F]
- MOV SS,[0007]
- PUSH CX
- SUB BX,+0E ; simulate register storage space of DOS exec
- PUSH BX
- PUSH AX
- CALL 3909 ; undo INT 2Fh
- CALL 0A30 ; returns by way of switching to protected mode
- CALL 34A6
- CALL 38F7
- CALL 38E5
- CALL 3930
- CALL 3954
- POP AX
- POP BX
- POP CX
- MOV DX,[000B] ; still in protected mode
- MOV ES,DX
- MOV DX,[006C]
- ES:
- MOV [0010],DX
- ES:
- MOV [000A],CX ; dpmiload's PSP termination address offset
- MOV ES,DX
- ES:
- MOV [002E],BX ; client's last dos stack
- ES:
- MOV [0030],AX
- MOV AX,4C00
- INT 21
- */
-
- /* ---------- FIX ----------
-
- MOV AX,SS ; segment=int 2Fh vector,offset=386d
- MOV BP,SP
- LES CX,[BP+04] ; ES not needed now I'm pretty sure
- MOV SP,[000F]
- MOV SS,[0007]
- PUSH AX
- SUB BP,+0E ; simulate register storage space of DOS exec
- PUSH BP
- PUSH CX ; push full terminate address (ES:CX)
- PUSH ES
- NOP
- CALL 3909 ; undo INT 2Fh
- CALL 0A30 ; returns by way of switching to protected mode
- CALL 34A6
- CALL 38F7
- CALL 38E5
- CALL 3930
- CALL 3954
- MOV DX,[006C] ; still in protected mode
- MOV DS,[000B]
- MOV [0010],DX
- POP [000C] ; FIX!! dpmiload's PSP termination address segment
- POP [000A] ; dpmiload's PSP termination address offset
- MOV DS,DX
- POP [002E] ; client's last dos stack
- POP [0030]
- JMP 38B9
- JMP 38BB
- MOV AX,4C00 ; exit
- INT 21
- */
-